#include"FaceRecognizer.h"
#include<string>
#include<memory>
#include<iostream>
#include<vector>
#include<regex>
#include<fstream>
#include"opencv2\opencv.hpp"

using std::cout;
using std::endl;
using std::string;
using std::pair;
using std::vector;
using std::fstream;
using std::ios;
using cv::Mat;

pair<std::string, vector<float>> process_oneline(const std::string & str)
{
	std::regex re(" ");
	std::sregex_token_iterator
		first{ str.begin(), str.end(), re, -1 },
		last;
	std::vector<string> str_line{ first, last };

	string person_id = str_line[0];
	std::vector<float> feature(str_line.size() - 1, 0.0f);
	std::transform(str_line.begin() + 1, str_line.end(), feature.begin(),
		[](const string& s)->float {return std::stof(s); });

	return make_pair(person_id, std::move(feature));
}

string get_name_from_filename(const string& image_name)
{
	auto pos = image_name.find_first_of('_');
	return image_name.substr(0, pos);
}

int main()
{
	if (caffe::GPUAvailable()) {
		printf("GPU is available\n");
		caffe::SetMode(caffe::GPU, 0);
	}
	else {
		printf("Only CPU is available\n");
	}

	std::string face_rec_model = "../model/facerec/sphereface_model_adam_iter_27000.caffemodel";
	std::string face_rec_deploy = "../model/facerec/sphereface_deploy.prototxt";

	std::unique_ptr<fr::FaceRecognizer> m_face_recognizer = std::make_unique<fr::FaceRecognizer>();

	if (!m_face_recognizer->load_model(face_rec_deploy, face_rec_model))
	{
		std::cout << "can not load face detection model!" << std::endl;
		return false;
	}

	//load mean file
	std::string mean_file = "../model/facerec/feature_mean27.txt";
	if (!m_face_recognizer->load_mean(mean_file)) {
		cout << "Can't load feature mean file" << endl;
		return false;
	}

	std::string facedb_rec = "../database/database_blur.txt";
	fstream rec_file;
	std::map<std::string, vector<float>> rec_features;
	rec_file.open(facedb_rec, ios::in | ios::out | ios::app);
	if (!rec_file)
		std::cerr << "can not open database record file" << endl;

	std::string rec_line;
	while (std::getline(rec_file, rec_line))
	{
		auto&& feature = process_oneline(rec_line);

		rec_features.insert(feature);

		std::string person_name = get_name_from_filename(feature.first);
		m_face_recognizer->add_person(person_name, feature.second);
	}

	rec_file.clear();
	rec_file.close();

	string test_img = "../database/image112x96/baoshuyuan_1.JPG";
	Mat image = cv::imread(test_img);
	cv::imshow("test", image);
	cv::waitKey(5);
	auto info = m_face_recognizer->identify(image);
	cout << "person name: " << info.first << " score: " << info.second << endl;

	system("pause");
}